Android et ses System-Services
Utiliser le téléphone et ses outils
Quelques "System-Services"
Un terminal Android possède souvent de nombreuses fonctionnalités : un acceléromètre, un GPS, un vibreur, un lecteur NFC (Near Field Communication), et bien d'autres.
Chacuns de ces éléments est représenté par une classe particulière, qui permet de lire et de controller le matériel.
Ces classes sont toutes très différentes, mais sont toutes récupérées de la même manière : avec la méthode getSystemService(nomduservice)
Les services sont partagés entre toutes les applications. Certaines applications peuvent les modifier pendant l'exécution de notre programme.
Quelques services et leur classe associée :
Code du service | Nom de la classe | Quelques possibilités |
---|---|---|
TELEPHONY_SERVICE | TelephonyManager | Pour savoir si le téléphone est décroché, connaître l'opérateur, le numéro de série de la carte SIM... |
DISPLAY_SERVICE | DisplayManager | Récupérer la liste des écrans connectés... |
AUDIO_SERVICE | AudioManager | Vérifier et controller le niveau sonnore, jouer des sons "systemes", ... |
ALARM_SERVICE | AlarmManager | Demander au système de lancer l'application à une heure précise, ... |
ACTIVITY_SERVICE | ActivityManager | Accéder à la liste des processus lancés, accéder à des information sur la mémoire, ... |
USB_SERVICE | UsbManager | (API 12) Accéder a des informations si un accéssoire est connecté, communiquer avec un accéssoire, ... |
LOCATION_SERVICE | LocationManager | Connaitre la position GPS du téléphone, être notifié d'un déplacement du téléphone. |
VIBRATOR_SERVICE | Vibrator | Activer le vibreur. |
LAYOUT_INFLATER_SERVICE | LayoutInflater | Utiliser dynamiquement des layouts |
Tous les services sur la documentation de la classe Context (dont Activity hérite) : http://developer.android.com/reference/android/content/Context.html
A noter que l'utilisation de ces services demandes souvent la déclaration de permissions dans le manifest.
Pour info, la liste complète des permissions se trouve aussi sur la doc d'Android : http://developer.android.com/reference/android/Manifest.permission.html
Par exemple, pour accéder à une instance du service "VIBRATOR_SERVICE", il faut, dans une activity :
Vibrator vibratorService = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
Ensuite, il est possible d'acceder aux méthodes de cette classe, par exemple :
Vibrator vibratorService = (Vibrator) this.getSystemService(VIBRATOR_SERVICE); if (vibratorService.hasVibrator()) { vibratorService.vibrate(1000); }
Le LOCATION_SERVICE
Le LOCATION_SERVICE permet de connaitre et de suivre la géolocalisation du terminal grace à la puce GPS ou au réseau cellulaire (moins précis).
La géolocalisation est représentée par un objet Location, qui contient (entre autre) des méthodes getLatitude() et getLongitude().
Pré-requis
L'utilisation de ce service nécessite :
- Les permissions ACCESS_COARSE_LOCATION et/ou ACCESS_FINE_LOCATION.
- Baser son projet sur la Google API (et pas seulement Android).
- Configurer l'émulateur pour utiliser la Google API.
Le principe
Dernière position connue
La classe LocationManager permet d'accéder aux fournisseurs de position : GPS_PROVIDER, NETWORK_PROVIDER ou PASSIVE_PROVIDER.
Le moyen le plus simple est d'espérer qu'une autre application à déja utilisé le service et de simplement demander quelle est la derniere position connue, ce qui permet d'économiser l'énergie, puisque cette méthode n'active aucun matériel particulier.
LocationManager lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); Location lastGpsLoc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER)); Location lastNetLoc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)); if (lastGpsLoc != null) { System.out.println("Derniere position connue (GPS) : "); System.out.println("Latitude: " + lastGpsLoc.getLatitude()); System.out.println("Longitude: " + lastGpsLoc.getLongitude()); } if (lastNetLoc != null) { System.out.println("Derniere position connue (NETWORK) : "); System.out.println("Latitude: " + lastGpsLoc.getLatitude()); System.out.println("Longitude: " + lastGpsLoc.getLongitude()); }
Activer les notifications
Pour activer et être notifié de la position réelle du terminal, il faut utiliser l'interface LocationListener. Les méthodes de cette interface sont :
void onLocationChanged(Location newLocalisation); void onProviderDisabled(String provider); void onProviderEnabled(String provider); void onStatusChanged(String provider, int status, Bundle extras);
Il suffit alors d'utiliser la méthode requestLocationUpdates(...) du service pour demander à être notifié des changements de position en lui passant une classe qui implémente cette interface. Cela peut être l'activity, ou une autre classe crée pour l'occasion.
La signature de la méthode :
void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener); //String provider : le fournisseur (GPS, NETWORK ou PASSIVE) //long minTime : temps minimal entre chaque notification (en ms) //float minDistance : la distance minimale entre chaque notification (en m). //LocationListener listener : l'objet qui sera notifié.
LocationManager lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, this);
Il est aussi possible de se désabonner de ces notifications :
lm.removeUpdates(this);
Exemple complet :
package com.example.geoloctest1; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.app.Activity; import android.util.Log; public class MainActivity extends Activity implements LocationListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LocationManager lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); } @Override public void onLocationChanged(Location newLoc) { System.out.println("Nouvelle position : " + newLoc.getLatitude() + ", " + newLoc.getLongitude()); } @Override public void onProviderDisabled(String provider) { System.out.println("Fournisseur desactive : "+ provider); } @Override public void onProviderEnabled(String provider) { System.out.println("Fournisseur active : "+ provider); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { System.out.println("Status change : " + provider + " = " + status); } }
Tester sur le simulateur
Il est possible de simuler des déplacements pour le simulateur, ainsi que d'autres actions.
Il faut pour cela utiliser la vue "DDMS" dans Eclipse.
Cette vue nous permet d'accéder à un onglet "Emulator Control", qui nous permet d'envoyer des ordres au simulateur pour voir comment notre application réagit : Changer le l'état de la connection réseau, simuler un appel entrant ou envoyer une position au GPS.
Exercice 1
Réaliser une application qui affiche la géolocalisation actuelle (latitude, longitude) dans une TextView.
Etapes
Annexes
Permissions:
A placer juste avant la balise "application".
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Exercice 2
Intégrer la géolocalisation dans l'application météo
Annexes
Changer la "target" d'un projet:
Sélectionner le projet, puis bouton droit "properties". Dans la catégorie "Android", la liste des "target" apparait à droite.